package dbc;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SyntaxHandler {

    protected String expression;
    private StringWriter generatedCode;
    private PrintWriter codeWriter;

    public SyntaxHandler(String expression) {
        this.expression = expression;
        generatedCode = new StringWriter();
        codeWriter = new PrintWriter(generatedCode);
    }

    public String getProcessedExpression() {
        return expression;
    }

    public String getGeneratedCode() {
        return generatedCode.toString();
    }

    public void processExpression() {
        processForall();
        processExist();
    }

    public void processForall() {
        Pattern forallRegex = Pattern.compile("\\$forall([^{]*)\\{([^}]*)\\}");
        Matcher m = forallRegex.matcher(expression);

        StringBuffer processedExpression = new StringBuffer();

        int i = 1;
        while(m.find()) {
            String resultName = "forallResult" + i;

            codeWriter.println("boolean " + resultName + " = true;");
            codeWriter.println("for" + m.group(1) + "{");
            codeWriter.println("if(!(" + m.group(2) + ")) {");
            codeWriter.println(resultName + " = false;");
            codeWriter.println("break; }");
            codeWriter.println("}");

            //replace $forall(...){exp} by forallResulti
            m.appendReplacement(processedExpression, resultName);
            i++;
        }
        m.appendTail(processedExpression);

        expression = processedExpression.toString();
    }

    public void processExist() {
        Pattern existRegex = Pattern.compile("\\$exists([^{]*)\\{([^}]*)\\}");
        Matcher m = existRegex.matcher(expression);

        StringBuffer processedExpression = new StringBuffer();

        int i = 1;
        while(m.find()) {
            String resultName = "existResult" + i;

            codeWriter.println("boolean " + resultName + " = false;");
            codeWriter.println("for" + m.group(1) + "{");
            codeWriter.println("if(" + m.group(2) + ") {");
            codeWriter.println(resultName + " = true;");
            codeWriter.println("break; }");
            codeWriter.println("}");

            //replace $exist(...){exp} by existResulti
            m.appendReplacement(processedExpression, resultName);
            i++;
        }
        m.appendTail(processedExpression);

        expression = processedExpression.toString();
    }
}
